﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using devtm.Helpers;
using System.Text.RegularExpressions;
using devtm.Collections;
using System.Threading;
using devtm.Configuration.Designers;


namespace devtm.Editor.Configuration.Customs
{

    public class CustomProperty : INotifyPropertyChanged
    {


        public CustomProperty()
        {

        }
 

        #region Generate New Item

        public void Create(PropertyInfo prop)
        {

            #region Labels

            CustomLabel displayName = Display.Add(new CustomLabel()
            {
                Culture = Thread.CurrentThread.CurrentCulture.ThreeLetterWindowsLanguageName,
                Text = string.Empty
            });

            CustomLabel description = Description.Add(new CustomLabel()
            {
                Culture = Thread.CurrentThread.CurrentCulture.ThreeLetterWindowsLanguageName,
                Text = string.Empty
            });

            #endregion

            foreach (Attribute attr in Attribute.GetCustomAttributes(prop))
            {

                Url = String.Empty;

                if (attr.GetType().FullName.StartsWith("System.Configuration") ||
                attr.GetType().IsOfType(
                typeof(System.Configuration.SectionInformation)
                ))
                    break;

                if (attr is LinkCustomDesignerAttribute)
                    Url = (attr as LinkCustomDesignerAttribute).Url.OriginalString;

                else if (attr is DisplayNameAttribute)
                    displayName.Text = (attr as DisplayNameAttribute).DisplayName;

                else if (attr is DescriptionAttribute)
                    description.Text = (attr as DescriptionAttribute).Description;
                
                else
                {

                    CustomDescription a;

                    if (Desc.ContainsKey(attr.GetType().AssemblyQualifiedName))
                        a = Desc[attr.GetType().AssemblyQualifiedName];
                    else
                        a = Desc.Add(new CustomDescription()
                        {
                            @Type = attr.GetType().AssemblyQualifiedName,
                            LastUpdate = DateTime.Now
                        });

                    a.PropertyChanged += c_PropertyChanged;

                    a.Create(attr);

                }

                LastUpdate = DateTime.Now;
            }

            if (string.IsNullOrEmpty(displayName.Text))
            {
                foreach (Match t in Reg.Matches(prop.Name))
                    displayName.Text = displayName.Text + t.Value + " ";
                displayName.Text = displayName.Text.Trim();

            }
     
        }

        #endregion

        #region Properties


        public IndexedObservableCollection<CustomLabel, string>
            Display = new IndexedObservableCollection<CustomLabel, string>
                (c => c.Culture);

        public IndexedObservableCollection<CustomLabel, string>
            Description = new IndexedObservableCollection<CustomLabel, string>
                (c => c.Culture);

        private string _url;
        public string Url
        {
            get
            {
                return _url;
            }
            set
            {
                if (_url == value)
                    return;
                _url = value;

                PropertyChange("Url");
            }
        }

        public string PropertyType { get; set; }

        private DateTime _LastUpdate;
        public DateTime LastUpdate
        {
            get
            {
                return _LastUpdate;
            }
            set
            {
                if (_LastUpdate == value)
                    return;
                _LastUpdate = value;

                PropertyChange("LastUpdate");
            }
        }

        public string Name { get; set; }

        public IndexedObservableCollection<CustomDescription, string>
            Desc = new IndexedObservableCollection<CustomDescription, string>
                (c => c.Type);

        #endregion

        #region Properties changed
 
        static System.Text.RegularExpressions.Regex Reg = new System.Text.RegularExpressions.Regex("[A-Z]+[a-z]*");


        void c_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "LastUpdate")
                LastUpdate = (sender as CustomDescription).LastUpdate;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void PropertyChange(string p)
        {

            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(p));

            if (p != "LastUpdate")
                LastUpdate = DateTime.Now;
            
        }

        #endregion

    }
}
